#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#include <signal.h>

#include "tool_log.h"

static struct
{
	pid_t pid;
	unsigned int checksum;
} lock;

static int checksum(pid_t *p)
{
	return ((char *)p)[0] + ((char *)p)[1] + ((char *)p)[2] + ((char *)p)[3];
}

static pid_t read_last_pid(const char *pid_path)
{
	FILE *pf = NULL;
	pf = fopen(pid_path, "r");
	if(NULL != pf)
	{
		fread(&lock, sizeof(lock), 1, pf);
		fclose(pf);
	}
	return lock.checksum == checksum(&lock.pid) ? lock.pid : 0;
}

int init_mutex(const char *pid_path)
{
	char proc[1024] = {0};
	pid_t pid = (pid_t)0;

	if(0 == access(pid_path, F_OK))
	{
		pid = read_last_pid(pid_path);
		if(0 != pid)
		{
			snprintf(proc, sizeof(proc), "/proc/%d", pid);
			if(0 == access(proc, F_OK))
			{
				0 == kill(pid, SIGKILL) ? logout("kill old server success") : logout("unable to kill previous proceess, maybe it was exit");
				return EXIT_SUCCESS;
			}
			logout("previous proceess was not exist");
			return EXIT_SUCCESS;
		}
		logout("bad pid lock file");
		return EXIT_FAILURE;
	}
	else
	{
		logout("pid lock file was not exist");
		return EXIT_SUCCESS;
	}
}

int create_mutex(const char *pid_path)
{
	FILE *pf = NULL;

	lock.pid = getpid();
	lock.checksum = checksum(&lock.pid);

	pf = fopen(pid_path, "w");
	if(NULL != pf)
	{
		fwrite(&lock, sizeof(lock), 1, pf);
		fclose(pf);
		return EXIT_SUCCESS;
	}
	return EXIT_FAILURE;
}
